package cliente.TwiterApiCliente;

import cliente.auxiliar.GereErros;
import cliente.auxiliar.GereOperacoes;
import cliente.domain.Status;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import cliente.responsehandler.xml.XmlUserFolloingFollowersHandler;
import sun.misc.BASE64Encoder;
import java.net.URLEncoder;

import java.io.IOException;
import cliente.domain.User;
import cliente.gui.Erro;
import cliente.responsehandler.xml.XmlSearchResponseHandler;
import cliente.responsehandler.xml.XmlUserTweetsResponseHandler;
import java.net.URI;
import java.util.Vector;
import org.apache.http.client.methods.HttpPost;

public class TwitterApiClient {
    protected HttpClient httpClient;
    protected GereOperacoes gestor = null;
    protected GereErros erros = null;

    public TwitterApiClient() {
        this.init();
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Get e Set
    public GereOperacoes getGestor() {
        return gestor;
    }

    public void setGestor(GereOperacoes gestor) {
        this.gestor = gestor;
    }

    public GereErros getErros() {
        return erros;
    }

    public void setErros(GereErros erros) {
        this.erros = erros;
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FIM
    public void init() {
        this.httpClient = new DefaultHttpClient();
        this.erros = new GereErros(gestor);
    }

    public void terminate() {
        this.httpClient.getConnectionManager().shutdown();
    }


    /*
     * -------------------------------------------------------------------------
     *
     *              TRABLHO PRATICO 5
     * 
     * -------------------------------------------------------------------------
     */


        /*
     * -----------------------------------
     *      Login
     * -----------------------------------
     */

    public void doLogintWithCredentials(String nickname, String pass) {
        String username = nickname;
        String password = pass;
        String credentials = new BASE64Encoder().encode((username + ":" + password).getBytes());

        HttpGet request = null;
        request = new HttpGet("http://twitter.com/account/verify_credentials.xml");

        User user;
        request.setHeader("Authorization", "Basic " + credentials);
        ResponseHandler<Vector<User>> responseH = new XmlUserFolloingFollowersHandler(erros);
        Vector<User> resposta = null;

        try {
            resposta = this.httpClient.execute(request, responseH);
        } catch (IOException e) {
            System.err.println("Failed to execute GET to " + request.getURI());
            //getErros().trataErros(resposta);
            //e.printStackTrace();
            //return;
        }
        if(resposta!=null){
            //System.out.println("Utilizador:" + resposta.get(0).getId() + " nome:" + resposta.get(0).getScreenName());
            user = resposta.get(0);
            if (user.getId() != null) {
                gestor.getArquivador().setLog_ok(true);
            } else {
                gestor.getArquivador().setLog_ok(false);
            }
        }
        else{
            gestor.getArquivador().setErro(true);
            Erro erro = new Erro("Servidor indisponivel!!!");
            erro.setVisible(true);
        }
    }

    public void doXmlRequestWithCredentials(String tipo) {
        String username = gestor.getArquivador().getNickname();
        String password = gestor.getArquivador().getPassword();
        String credentials = new BASE64Encoder().encode((username + ":" + password).getBytes());

        HttpGet request = null;

        String reqType = null;

        if ("followers".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            request = new HttpGet("http://twitter.com/statuses/followers/" + gestor.getArquivador().getNickname() + ".xml");
        }
        if ("following".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            request = new HttpGet("http://twitter.com/statuses/friends/" + gestor.getArquivador().getNickname() + ".xml");
        }
        if ("followers".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            request = new HttpGet("http://twitter.com/statuses/followers/" + gestor.getArquivador().getNickname() + ".xml");
        }
        if ("lista_tweets".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            request = new HttpGet("http://twitter.com/statuses/friends_timeline/" + gestor.getArquivador().getNickname() + ".xml");
        }


                    /*
             * -----------------------------------
             *      Metodos de GET
             * -----------------------------------
             */

        if (reqType.equals("GET")) {
            if ("followers".equalsIgnoreCase(tipo) || "following".equalsIgnoreCase(tipo)) {
                request.setHeader("Authorization", "Basic " + credentials);
                ResponseHandler<Vector<User>> responseH = new XmlUserFolloingFollowersHandler(erros);
                Vector<User> resposta = null;

                try {
                    resposta = this.httpClient.execute(request, responseH);
                } catch (IOException e) {
                    System.err.println("Failed to execute GET to " + request.getURI());

                }

                if (resposta != null) {
                    gestor.getArquivador().setErro(false);
                    String[] aux = new String[resposta.size()];
                    for (int i = 0; i < resposta.size(); i++) {
                        aux[i] = resposta.get(i).getScreenName();
                    }

                    if ("followers".equalsIgnoreCase(tipo)) {
                        gestor.getArquivador().setFollowers(aux);
                    }
                    if ("following".equalsIgnoreCase(tipo)) {
                        gestor.getArquivador().setFollowing(aux);
                    }
                }
            }

            if ("lista_tweets".equalsIgnoreCase(tipo)) {
                request.setHeader("Authorization", "Basic " + credentials);
                ResponseHandler<Vector<Status>> responseHandler = new XmlUserTweetsResponseHandler(erros);
                Vector<Status> resposta = null;

                try {
                    resposta = this.httpClient.execute(request, responseHandler);
                } catch (IOException e) {
                    System.err.println("Failed to execute GET to " + request.getURI());
                    gestor.getArquivador().setErro(true);
                    Erro erro = new Erro(e.getMessage());
                    erro.setVisible(true);

                }

                if (resposta != null) {
                    gestor.getArquivador().setErro(false);
                    Status[] aux = new Status[resposta.size()];
                    for (int i = 0; i < resposta.size(); i++) {
                        aux[i] = resposta.get(i);
                    }
                    gestor.getArquivador().setTweets(aux);
                }
            }
        }
    }

    public void doXmlRequestWithCredentialsAndLotsOfParametersAndWithAFunctionThatIsSupposedToDoStuffThatWeDontKnowYet(String tipo, String cenas) {
        String username = gestor.getArquivador().getNickname();
        String password = gestor.getArquivador().getPassword();
        String credentials = new BASE64Encoder().encode((username + ":" + password).getBytes());

        HttpGet request = null;
        HttpPost postReq = null;

        String reqType = null;

        if ("unfollow".equalsIgnoreCase(tipo)) {
            reqType = "POST";
            postReq = new HttpPost("http://twitter.com/friendships/destroy/" + cenas + ".xml");
        }
        if ("follow".equalsIgnoreCase(tipo)) {
            reqType = "POST";
            postReq = new HttpPost("http://twitter.com/friendships/create/" + cenas + ".xml");
        }
        if ("search".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            try {
                request = new HttpGet("http://api.twitter.com/1/users/search.xml?q=" + URLEncoder.encode(cenas, "UTF-8"));
                System.out.println("URL" + request.getURI());
            } catch (UnsupportedEncodingException ex) {
//                Logger.getLogger(TwitterApiClient.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        if ("detalhes".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            request = new HttpGet("http://twitter.com/users/show.xml?screen_name=" + cenas);
        }
        if ("lista_tweets".equalsIgnoreCase(tipo)) {
            reqType = "GET";
            try {
                request = new HttpGet("http://twitter.com/statuses/user_timeline.xml?screen_name=" + URLEncoder.encode(cenas, "UTF-8"));
            } catch (UnsupportedEncodingException ex) {
                //Logger.getLogger(TwitterApiClient.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        if ("tweet".equalsIgnoreCase(tipo)) {
            try {
                reqType = "POST";
                postReq = new HttpPost("http://twitter.com/statuses/update.xml?status=" + URLEncoder.encode(cenas, "UTF-8"));
            } catch (UnsupportedEncodingException ex1) {
                //System.out.println("[ERRO]Encoding Exeption: Problemas na codificacao do ficheiro!!!\n" + ex1.getMessage());
            } 
        }


        /*
         * -----------------------------------
         *      Efectuar Metodos de Get
         * -----------------------------------
         */

        if (reqType.equals("GET")) {
            Vector<User> resposta = null;

            if ("search".equalsIgnoreCase(tipo)) {
                request.setHeader("Authorization", "Basic " + credentials);
                ResponseHandler<Vector<User>> responseH = new XmlUserFolloingFollowersHandler(erros);

                try {
                    resposta = this.httpClient.execute(request, responseH);
                } catch (IOException e) {
                    System.err.println("Failed to execute GET to " + request.getURI());
                    e.printStackTrace();
                    //return;
                }

                if (resposta != null) {
                    gestor.getArquivador().setErro(false);
                    String[] aux = new String[resposta.size()];
                    User[] aux_pax = new User[resposta.size()];
                    for (int i = 0; i < resposta.size(); i++) {
                        aux[i] = resposta.get(i).getScreenName();
                        aux_pax[i] = resposta.get(i);
                    }
                    gestor.getArquivador().setPesquisa(aux_pax);
                    gestor.getArquivador().setNomes(aux);
                }
            }

            /*
             * -----------------------------------
             *      Listar Tweets
             * -----------------------------------
             */

            if ("lista_tweets".equalsIgnoreCase(tipo)) {
                request.setHeader("Authorization", "Basic " + credentials);
                ResponseHandler<Vector<Status>> responseHandler = new XmlSearchResponseHandler(erros);
                Vector<Status> tweets = null;

                try {
                    tweets = this.httpClient.execute(request, responseHandler);
                } catch (IOException e) {
                    System.err.println("Failed to execute GET to " + request.getURI());
                    //e.printStackTrace();
                    //return;
                }

                if (tweets != null) {
                    System.out.println("---Mensagem---" + tweets.size());
                    Status[] array = new Status[tweets.size()];
                    for (int i = 0; i < tweets.size(); i++) {
                        //System.out.println(i + " - " + tweets.get(i).getText());
                        array[i] = tweets.get(i);
                    }
                    gestor.getArquivador().setListaTweets(array);
                    //System.out.println("Updated---");
                }
            }

        }

        /*
         * -----------------------------------
         *      Efectuar Metodos de Post
         * -----------------------------------
         */

        try {
            if (reqType.equals("POST")) {
                postReq.setHeader("Authorization", "Basic " + credentials);
                BasicResponseHandler responseHandler = new BasicResponseHandler();
                String coiso = this.httpClient.execute(postReq, responseHandler);
            }
        } catch (IOException e) {
            //System.out.println("[ERRO]:" + e.getMessage());
            if("tweet".equalsIgnoreCase(tipo)){
                gestor.getArquivador().adicionaSms(cenas);
            }
            gestor.getArquivador().setErro(true);
            Erro erro = new Erro(e.getMessage());
            erro.setVisible(true);
        }

    }
}
